﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ProLinq.Projection.Visitors;
using ProLinq.Projection.Visitors.Optimization;
using ProLinq.Tests.Helpers;

namespace ProLinq.Tests.Projection
{
	[TestClass]
	public class FilterBuilderTests
	{
		private IQueryable<A> GetSource()
		{
			return new A[0].AsQueryable();
		}

		[TestMethod]
		public void LogicalExpressionIsBoolean()
		{
			var source = GetSource();
			var res = source.Intercept(q =>
			{
				var filterBuilder = new FilterBuilderVisitor();
				filterBuilder.ProcessedExpressionPart = source.Expression;
				filterBuilder.Visit(q.Expression);
				Assert.IsTrue(filterBuilder.FilterExpression.Body.Type == typeof(Boolean));

				return q.Execute();
			}).Where(a => a.DataInt1 == 10).Select(a => a.DataInt2).FirstOrDefault(i => i > 5);
		}

		[TestMethod]
		public void LogicalExpressionAccountsFirstOrDefaultPredicate()
		{
			var source = GetSource();
			var res = source.Intercept(q =>
			{
				var filterBuilder = new FilterBuilderVisitor();
				filterBuilder.ProcessedExpressionPart = source.Expression;
				filterBuilder.Visit(q.Expression);

				Assert.IsTrue(filterBuilder.FilterExpression.FindConstant(5));

				return q.Execute();
			}).Where(a => a.DataInt1 == 10).Select(a => a.DataInt2).FirstOrDefault(i => i > 5);
		}

		[TestMethod]
		public void LogicalExpressionAccountsAnonymousProjections()
		{
			var source = GetSource();
			var res = source.Intercept(q =>
			{
				var filterBuilder = new FilterBuilderVisitor();
				filterBuilder.ProcessedExpressionPart = source.Expression;
				filterBuilder.Visit(q.Expression);

				Assert.IsTrue(filterBuilder.FilterExpression.FindConstant(5));

				// TODO: write correct test chech here

				return q.Execute();
			}).Where(a => a.DataInt1 == 10).Select(a => new B { DataInt2 = a.DataInt2}).FirstOrDefault(i => i.DataInt2 > 5);
		}
	}
}
